package com.cloud.mall.exp;

import cn.hutool.json.JSONUtil;
import com.cloud.mall.constants.CommonConstant;
import com.cloud.mall.enums.ExcEnum;
import com.cloud.mall.result.ExceptionResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author: 梁二东
 * @Date: 2024/12/4 15:33
 * @Description: @RestControllerAdvice对网关没有任何作用。
 * <p>
 * gateway自动装配异常的配置类： ErrorWebFluxAutoConfiguration
 **/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    /**
     * 方法参数无效异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ExceptionResponse methodArgumentNotValidExc(MethodArgumentNotValidException ex, HttpServletRequest request) {
        StringBuilder errorMsg = new StringBuilder();
        BindingResult bindingResult = ex.getBindingResult();
        // 仅记录错误消息，而不打印堆栈
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errorMsg.append(fieldError.getField()).append(CommonConstant.COLON).append(fieldError.getDefaultMessage()).append(", ");
        }
        // 去掉最后一个逗号和空格
        if (errorMsg.length() > 0) {
            errorMsg.delete(errorMsg.length() - 2, errorMsg.length());
        }
        // 记录错误信息
        log.error("GlobalExceptionHandler捕获方法参数无效异常: {}", errorMsg);

        // 返回自定义异常
        CustomException fail = CustomException.fail(ExcEnum.BAD_REQUEST.getCode(), errorMsg.toString(), request.getRequestURI(), request.getMethod());
        return ExceptionResponse.fail(fail);
    }

    /**
     * 捕获自定义异常
     *
     * @param exp
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public ExceptionResponse customException(CustomException exp, HttpServletRequest request) {
        log.error("GlobalExceptionHandler捕获自定义异常:{}", JSONUtil.toJsonStr(exp));
        return ExceptionResponse.fail(exp, request.getRequestURI(), request.getMethod());
    }

    /**
     * 捕获全局Exception
     *
     * @param exp
     * @return
     */
    @ExceptionHandler(Exception.class)
    public ExceptionResponse unknownException(Exception exp, HttpServletRequest request) {
        ExceptionResponse customException = new ExceptionResponse();
        customException.setCode(-999);
        customException.setMessage("未知异常：" + exp.getMessage());
        customException.setPath(request.getRequestURI());
        customException.setMethod(request.getMethod());
        log.error("GlobalExceptionHandler捕获全局Unknown exception堆栈信息：", exp);
        return customException;
    }
}
